package com.totoro.tyrank.manager;

import com.totoro.tyrank.TyRank;
import com.totoro.tyrank.constants.StaticSystemVarConst;
import com.totoro.tyrank.data.ItemDisplayData;
import com.totoro.tyrank.data.RankingData;
import com.totoro.tyrank.handle.PaginatorHandler;
import com.totoro.tyrank.utils.ColorUtil;
import com.totoro.tyrank.utils.DateUtil;
import com.totoro.tyrank.utils.FileUtil;
import com.totoro.tyrank.utils.ListUtil;
import lombok.Getter;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

public class RankingManager {

    private final Plugin plugin;

    private final static File RANK_FOLDER = new File(TyRank.getInstance().getDataFolder().getPath() + StaticSystemVarConst.FILE_SEPARATOR + StaticSystemVarConst.RANK_CONFIG_DEFAULT_NAME);

    /* 所有排行榜(包括历史排行榜但不包括未启动的排行榜) */
    @Getter
    private Map<String, RankingData> rankDataMap;

    /* 当前排行榜 (不包括历史排行榜和未启动的排行榜)*/
    @Getter
    private Map<String, RankingData> currentRankDataMap;

    /* 历史排行榜 (不包括未启动的排行榜) */
    @Getter
    private Map<String, RankingData> historyRankDataMap;

    /* 所有没经过处理的排行榜预览领取集合 */
    @Getter
    private Map<String, Map<String, RankingData.RankingReceive>> allUntreatedRankingReceiveMap;

    /* 所有没经过处理的排行榜预览领取分页器 */
    @Getter
    private Map<String, PaginatorHandler<RankingData.RankingReceive>> allUntreatedRankingReceivePaginatorHandler;

    /* 总排行榜分页器 (包含当前和历史排行榜) */
    @Getter
    private PaginatorHandler<RankingData> rankPaginatorHandler;

    /* 当前排行榜分页器 */
    @Getter private PaginatorHandler<RankingData> currentRankPaginatorHandler;

    /* 历史排行榜分页器 */
    @Getter private PaginatorHandler<RankingData> historyRankPaginatorHandler;

    public RankingManager(Plugin plugin) {
        this.plugin = plugin;
    }

    /**
     * 生成默认文件和示例配置
     */
    public void createRankFile() {
        // 如果排行文件不存在则创建
        if(! RANK_FOLDER.exists()) {
            RANK_FOLDER.mkdirs();
        }
        // 存储默认的配置
        plugin.saveResource("rank/defaultRank.yml", true);
        plugin.getServer().getConsoleSender().sendMessage(StaticSystemVarConst.CONSOLE_PREFIX + ColorUtil.color("&f已生成默认配置."));
    }

    /**
     * 重载排行榜基础配置
     */
    public void reloadRank() {
        // 递归获取排行文件下的所有子文件
        rankDataMap = new HashMap<>();
        currentRankDataMap = new HashMap<>();
        historyRankDataMap = new HashMap<>();
        allUntreatedRankingReceiveMap = new HashMap<>();
        allUntreatedRankingReceivePaginatorHandler = new HashMap<>();
        reloadRank(null);
    }

    public void reloadRank(String rankId) {
        List<File> allRankFile = FileUtil.getAllFiles(RANK_FOLDER);
        List<String> rankIds = new ArrayList<>();
        if(null != rankId) {
            // 单个排行榜是否加载成功
            boolean isLoadOneRank = false;
            if (ListUtil.isNotBlank(allRankFile)) {
                for (File rankFile : allRankFile) {
                    if (rankFile.isFile()) {
                        YamlConfiguration rankYamlConfig = new YamlConfiguration();
                        try {
                            rankYamlConfig.load(rankFile);
                            ConfigurationSection rankConfig = rankYamlConfig.getConfigurationSection("rank");
                            // 获取rank全局ID
                            String id = rankConfig.getString("id");
                            if(id.equals(rankId)) {
                                boolean enable = rankConfig.getBoolean("enable");
                                if(! enable) {
                                    allRankFile.clear();
                                    break;
                                }
                                allRankFile.clear();
                                allRankFile.add(rankFile);
                                isLoadOneRank = true;
                                break;
                            }
                        } catch (IOException | InvalidConfigurationException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            // 如果rankId不是Null就判断是否加载成功
            if(! isLoadOneRank) {
                plugin.getServer().getConsoleSender()
                        .sendMessage(StaticSystemVarConst.CONSOLE_PREFIX +
                                ColorUtil.color("&c排行榜Id &e[" + rankId +"] &c加载失败，请检查该排行榜Id对应的文件是否存在且打开了该批号且内容是否正确"));
                return;
            }
        }

        // 正式加载
        if(ListUtil.isNotBlank(allRankFile)) {
            for (File rankFile : allRankFile) {
                if(rankFile.isFile()) {
                    try {
                        RankingData rankingData = new RankingData();
                        YamlConfiguration rankYamlConfig = new YamlConfiguration();
                        rankYamlConfig.load(rankFile);
                        ConfigurationSection rankConfig = rankYamlConfig.getConfigurationSection("rank");
                        // 获取rank全局ID
                        String id = rankConfig.getString("id");
                        // 检查全局ID是否重复
                        if(rankIds.contains(id)) {
                            plugin.getServer().getConsoleSender()
                                    .sendMessage(StaticSystemVarConst.CONSOLE_PREFIX + ColorUtil.color("&c排行配置文件 &e[" + rankFile.getName() +"] &c加载错误，全局ID &e[" + id + "] &c发生重复!"));
                            continue;
                        }
                        // 获取基础配置
                        String rankName = ColorUtil.color(rankConfig.getString("rank-name", id));
                        String valueName = ColorUtil.color(rankConfig.getString("value-name", "&f数值"));
                        String valueFormat = rankConfig.getString("value-format", "%.0f");
                        boolean enable = rankConfig.getBoolean("enable", false);
                        // 如果未启动，则不加载
                        if(! enable) {
                            plugin.getServer().getConsoleSender()
                                    .sendMessage(StaticSystemVarConst.CONSOLE_PREFIX + ColorUtil.color("&c排行配置文件 &e[" + rankFile.getName() +"] &c的enable为false，故暂不加载!"));
                            continue;
                        }
                        String rankBy = rankConfig.getString("rank-by");
                        // 检查该rankBy的PAPI变量是否注册
                        if (! PlaceholderAPI.containsPlaceholders(rankBy)) {
                            plugin.getServer().getConsoleSender()
                                    .sendMessage(StaticSystemVarConst.CONSOLE_PREFIX + ColorUtil.color("&c排行配置文件 &e[" + rankFile.getName() +"] &c加载错误，排行变量 &e[" + rankBy + "] &c不存在!"));
                            continue;
                        }
                        ItemDisplayData rankItemDisplay = getItemDisPlay(rankConfig.getConfigurationSection("item-display"));
                        int updateInterval = rankConfig.getInt("update-interval", 600);
                        long clearInterval = rankConfig.getLong("clear-interval", -1L);
                        String endTime = rankConfig.getString("end-time");
                        int maxStatistics = rankConfig.getInt("max-statistics", -1);
                        int minStatistics = rankConfig.getInt("min-statistics", -1);
                        boolean attributeLasting = rankConfig.getBoolean("attribute-lasting", false);
                        // 基础配置加载完毕

                        // 排行名次领取配置加载
                        ConfigurationSection rankingReceiveSection = rankConfig.getConfigurationSection("ranking-receive");
                        Map<Integer, RankingData.RankingReceive> rankingReceiveMap = new HashMap<>();
                        // 获取所有名次 (第一需求：确保所有名次都是唯一的，而且名次可能是1-100这样的分隔类型) (第二需求，同时统计一次未处理过的名次领取预览)
                        Set<String> rankingKeys = rankingReceiveSection.getKeys(false);
                        // 第二名次预览需求的Map
                        LinkedHashMap<String, RankingData.RankingReceive> untreatedReceiveMap = new LinkedHashMap<>(rankingKeys.size());
                        for (String rankingKey : rankingKeys) {
                            RankingData.RankingReceive rankingReceive = rankingData.new RankingReceive();
                            // 获取该名次的section
                            ConfigurationSection rankingSection = rankingReceiveSection.getConfigurationSection(rankingKey);
                            // 获取该名次的DisPlayItem
                            rankingReceive.setRankingText(rankingKey);
                            rankingReceive.setItemDisplay(getItemDisPlay(rankingSection.getConfigurationSection("item-display")));

                            // 获取该名次下的属性
                            ConfigurationSection attributeSection = rankingSection.getConfigurationSection("attribute");
                            RankingData.RankingReceive.Attribute attribute = rankingReceive.new Attribute();
                            if(null != attributeSection) {
                                ItemDisplayData itemDisplayData = getItemDisPlay(attributeSection.getConfigurationSection("item-display"));
                                List<String> giveAttribute = attributeSection.getStringList("give-attribute");
                                attribute.setItemDisplay(itemDisplayData);
                                attribute.setGiveAttribute(giveAttribute);
                            }

                            // 获取该名次下的奖励
                            ConfigurationSection rewardSection = rankingSection.getConfigurationSection("reward");
                            ItemDisplayData itemDisPlay = getItemDisPlay(rewardSection.getConfigurationSection("item-display"));
                            List<String> showItems = rewardSection.getStringList("show-items");
                            List<String> rewardAction = rewardSection.getStringList("action").stream().map(ColorUtil::color).collect(Collectors.toList());
                            RankingData.RankingReceive.Reward reward = rankingReceive.new Reward(itemDisPlay, showItems, rewardAction);
                            // 将属性和奖励设置到名次领取对象中
                            rankingReceive.setAttribute(attribute);
                            rankingReceive.setReward(reward);
                            // 统计大概的名次领取预览

                            // 获取到的ranking可能是只有一个的，但是要统一变成集合处理，然后这里每个名次都要记上，跟上面的不一样
                            List<Integer> rankings = ListUtil.parseRange(rankingKey);
                            for (Integer ranking : rankings) {
                                // 给每个名次都push到Map中
                                rankingReceiveMap.put(ranking, rankingReceive);
                            }
                            untreatedReceiveMap.put(rankingKey, rankingReceive);
                        }
                        // 设置未处理名次领取预览数据
                        allUntreatedRankingReceiveMap.put(id, untreatedReceiveMap);
                        allUntreatedRankingReceivePaginatorHandler.put(id, new PaginatorHandler<>(new ArrayList<>(untreatedReceiveMap.values()), 27));
                        // 获取完成，赋值RankData且push到最大MAP中
                        rankingData.setId(id);
                        rankingData.setRankName(rankName);
                        rankingData.setValueName(valueName);
                        rankingData.setValueFormat(valueFormat);
                        rankingData.setEnable(enable);
                        rankingData.setRankBy(rankBy);
                        rankingData.setItemDisplay(rankItemDisplay);
                        rankingData.setUpdateInterval(updateInterval);
                        rankingData.setClearInterval(clearInterval);
                        rankingData.setEndTime(DateUtil.strFormatDate(endTime));
                        rankingData.setMaxStatistics(maxStatistics);
                        rankingData.setMinStatistics(minStatistics);
                        rankingData.setAttributeLasting(attributeLasting);
                        rankingData.setRankingReceiveMap(rankingReceiveMap);
                        // 添加到最大的Map
                        plugin.getServer().getConsoleSender()
                                .sendMessage(StaticSystemVarConst.CONSOLE_PREFIX + ColorUtil.color("&b成功载入排行配置文件: &e[" + rankFile.getName() + "(" + id + ")]"));
                        // 添加全局排行榜
                        rankDataMap.put(id, rankingData);
                        // 添加当前排行榜
                        if(! DateUtil.isCurrentTimeAfter(endTime)) {
                            currentRankDataMap.put(id, rankingData);
                        } else {
                            historyRankDataMap.put(id, rankingData);
                        }
                        // 添加全局ID
                        rankIds.add(id);
                    } catch (Exception e) {
                        e.printStackTrace();
                        plugin.getServer().getConsoleSender()
                                .sendMessage(StaticSystemVarConst.CONSOLE_PREFIX + ColorUtil.color("&c排行配置文件 &e[" + rankFile.getName() +"] &c加载错误，请检查文件内容是否正确"));
                    }
                }
            }
            // 启动分页器
            rankPaginatorHandler = new PaginatorHandler<>(new ArrayList<>(rankDataMap.values()), 7);
            currentRankPaginatorHandler = new PaginatorHandler<>(new ArrayList<>(currentRankDataMap.values()), 7);
            historyRankPaginatorHandler = new PaginatorHandler<>(new ArrayList<>(historyRankDataMap.values()), 7);
            plugin.getServer().getConsoleSender()
                    .sendMessage(StaticSystemVarConst.CONSOLE_PREFIX + ColorUtil.color("&b本次共载入: &e[" + rankIds.size() +"] &b个排行配置"));
        }

    }

    /**
     * 获取配置里统一格式的item-display节点对象
     * @param itemDisPlaySection
     * @return
     */
    private ItemDisplayData getItemDisPlay(ConfigurationSection itemDisPlaySection) {
        int id = itemDisPlaySection.getInt("id", -1);
        int data = itemDisPlaySection.getInt("data", -1);
        String name = ColorUtil.color(itemDisPlaySection.getString("name", ""));
        List<String> lore = itemDisPlaySection.getStringList("lore").stream().map(ColorUtil::color).collect(Collectors.toList());
        return new ItemDisplayData(id, data, name, lore);
    }

    /**
     * 获取排行预览对象根据排行榜ID和名次
     * @param rankId
     * @param ranking
     * @return
     */
    public RankingData.RankingReceive getRankingReceiveByRankIdAndRanking(String rankId, Integer ranking) {
        if (! rankDataMap.containsKey(rankId)) {
            return null;
        }
        RankingData rankingData = rankDataMap.get(rankId);
        Map<Integer, RankingData.RankingReceive> rankingReceiveMap = rankingData.getRankingReceiveMap();
        if(! rankingReceiveMap.containsKey(ranking)) {
            return null;
        }
        return rankingReceiveMap.get(ranking);
    }


}
